home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / SYQUEST / SQHDX / PACKET.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  8.9 KB  |  320 lines

  1. * ---------------- Low-level driver ----------------
  2. *----- Hardware:
  3. dmactlr        equ    $ffff8604    ; address of DMA controller
  4. wdc        equ    $0        ; DMA controller port
  5. wdl        equ    $2        ; DMA controller
  6. wdcwdl        equ    wdc        ; used for long writes
  7.  
  8. dmahi        equ    $ffff8609    ; DMA address - high byte
  9. dmamid        equ    dmahi+2        ;           - middle byte
  10. dmalow        equ    dmamid+2    ;          - low byte
  11.  
  12. gpip        equ    $fffffa01
  13.  
  14.  
  15. *----- Tunable:
  16. ltimeout    equ    450000        ; long-timeout (3 S)
  17. stimeout    equ    15000        ; short-timeout (100 mS)
  18.  
  19. SIXBYTE        equ    4        ; length of command - 2
  20. cmdwdl:        dc.w    0        ; wdl value for sending command byte
  21. datawdl:    dc.w    0        ; wdl value for sending data byte
  22. ctrlwdl:    dc.w    0        ; wdl value for sending control byte
  23. cmdblk:        dcb.b    6,0        ; command block
  24. ncmd:        dc.b    0        ; flag for continous command
  25. .even
  26.  
  27. *+
  28. * _docmd() - send a given packet to the controller and wait till command
  29. *         is completed
  30. *       - there is a 2nd entry point at _scmd if NO DMA is involved
  31. * Synopsis:    WORD _docmd(buf_addr)    /* Entry point for command with DMA */
  32. *         LONG buf_addr;        4(sp).l
  33. *
  34. *        WORD _scmd()        /* Entry point for command w/o DMA */
  35. *
  36. * Assumed:    d1.w = command block length - 2
  37. *        d2.l - if MSB set = writing to DMA
  38. *               if MSB not set = reading from DMA
  39. *             - d2.w = # sectors of DMA involved
  40. *
  41. *-
  42.     .globl    _docmd
  43.     .globl    _shdc
  44.     .globl    _shdc1
  45. _docmd:    st    flock            ; lock FIFO (DMA channel)
  46.     move.b    7(sp),dmalow        ; else set DMA to point to
  47.     move.b    6(sp),dmamid        ;      buffer for transfer
  48.     move.b    5(sp),dmahi
  49.     movea.l    #dmactlr,a0        ; a0 = address of DMA controller
  50.     
  51.     moveq    #31,d0            ; d0 = bit number to be tested
  52.     bclr.l    d0,d2            ; reading from DMA?
  53.     beq    rdma            ; if so, go set DMA to read state
  54.                     ; direction of data flow: ST -> DMA
  55.     move.w    #$188,cmdwdl        ; wdl for command byte = $188
  56.     move.w    #$18a,datawdl        ; wdl for data byte = $18a
  57.     move.w    #$100,ctrlwdl        ; wdl for control byte = $100
  58.     move.w    #$90,wdl(a0)        ; reset DMA controller
  59.     move.w    #$190,wdl(a0)        ;     and leave in write state
  60.     move.w    d2,wdc(a0)        ; # of 512 bytes sectors
  61.     move.w    #$18a,wdl(a0)        ; point back to parameter port
  62.     bra    _shdc1            ; go on to send command block
  63.                     ; direction of data flow: DMA -> ST
  64. rdma:    move.w    #$88,cmdwdl        ; wdl for command byte = $88
  65.     move.w    #$8a,datawdl        ; wdl for data byte = $8a
  66.     move.w    #$00,ctrlwdl        ; wdl for control byte = $00
  67.     move.w    #$190,wdl(a0)        ; reset DMA controller
  68.     move.w    #$90,wdl(a0)        ;     and leave in read state
  69.     move.w    d2,wdc(a0)        ; # of 512 bytes sectors
  70.     move.w    #$8a,wdl(a0)        ; point back to parameter port
  71.     bra    _shdc1            ; go on to send command block
  72.  
  73. _shdc:    st    flock            ; lock FIFO (DMA channel)
  74.     move.w    #$88,cmdwdl        ; wdl for command byte = $88
  75.     move.w    #$8a,datawdl        ; wdl for data byte = $8a
  76.     move.w    #$8a,ctrlwdl        ; wdl for control byte = $8a
  77.     movea.l    #dmactlr,a0        ; a0 = address of DMA controller
  78.  
  79. _shdc1:    lea    cmdblk,a1        ; a1 = ptr to command block
  80.     move.w    cmdwdl,wdl(a0)        ; sending a command
  81.     clr.w    d0            ; clear d0
  82.     move.w    #SIXBYTE,d1        ; length of command 
  83. shdc2:    move.b    (a1)+,d0        ; d0.b = command byte to be sent
  84.     swap    d0            ; hi word of d0.l = command byte
  85.     move.w    datawdl,d0        ; d0.w = next byte will be an operand
  86.     move.l    d0,wdcwdl(a0)        ; write command to DMA
  87.     bsr    _qdone            ; wait a little while
  88.     bmi    dcmd            ; if timeout, done with timeout error
  89.     dbra    d1,shdc2        ; do until all command bytes are sent
  90.                     ; now send the control byte
  91.     move.b    (a1),d0            ; last byte from command byte
  92.     swap    d0            ; hi word of d0.l = command byte
  93.     move.w    ctrlwdl,d0        ; d0.w = wdl value for contro byte
  94.     move.l    d0,wdcwdl(a0)        ; write to controller
  95.                     ; wait for command completion
  96.     bsr    _fdone            ; wait for operation complete
  97. dlcmd:    move.l    _hz_200,d1        ; delay 2 ticks for completion byte
  98.     addq.l    #2,d1
  99. wait:    cmp.l    _hz_200,d1        
  100.     bcc    wait
  101.     tst.w    d0            ; was it successful?
  102.     bmi    dcmd            ; if timed out, return
  103.  
  104.     move.w    datawdl,wdl(a0)        ; else point back to parameter port
  105.     move.w    wdc(a0),d0        ; get the result
  106.     andi.w    #$00ff,d0        ; (clean it up), if non-zero should
  107.                     ; do a ReadSense command to learn more
  108.     bne    dcmd            ; if not successful, return
  109.  
  110.     tst.b    ncmd            ; else, another command right after?
  111.     beq    dcmd            ; if not, return normally
  112.     tst.w    d0
  113.     rts                ; else, return now
  114.  
  115. dcmd:    move.w    #$80,wdl(a0)        ; Landon's code seems to presume we
  116.     nop                ;  put this back to $80
  117.     clr    flock            ; NOW, signal that we are done
  118.     tst.w    d0            ; set condition code to reveal result
  119.     rts
  120.  
  121.  
  122.  
  123. *+
  124. * LONG _qdone() - Wait for command byte handshake
  125. * LONG _fdone() - Wait for operation complete
  126. * Passed:    nothing
  127. *
  128. * Returns:    EQ: no timeout
  129. *        MI: timeout condition
  130. *
  131. * Uses:        D0
  132. *
  133. * each pass through the loop takes 6.75 uS
  134. *-
  135. _fdone:    move.l    #ltimeout,tocount
  136.     bra    qd1
  137.  
  138. _qdone:
  139.     move.l    #stimeout,tocount
  140.  
  141. qd1:    subq.l    #1,tocount        ; drop timeout count
  142.     bmi    qdq            ; (i give up, return NE)
  143.     btst    #5,gpip            ; interrupt?
  144.     bne    qd1            ; (not yet)
  145.  
  146.     moveq    #0,d0            ; return EQ (no timeout)
  147.     rts
  148.  
  149. qdq:    moveq    #-1,d0
  150.     rts
  151.  
  152.  
  153.  
  154. *-
  155. * clrcmdblk()
  156. *
  157. * Clear the command block for the driver call
  158. *+
  159. clrcmdblk:
  160.     lea    cmdblk,a0        ; a0 = ptr to command block
  161.     move.l    #0,(a0)+
  162.     move.w    #0,(a0)
  163.     rts
  164.  
  165.  
  166.  
  167. *-
  168. * _hread(sectno, count, buf, dev)
  169. * LONG sectno;         4(sp)
  170. * WORD count;         8(sp)
  171. * LONG buf;        $a(sp)    $b=high, $c=mid, $d=low
  172. * WORD dev;        $e(sp)
  173. *
  174. * Returns:    -1 on timeout
  175. *        0 on success
  176. *        nonzero on error
  177. *
  178. *-
  179. READ    equ    $8
  180.     .globl    _hread
  181. _hread:    bsr    clrcmdblk        ; clear the command block
  182.     lea    cmdblk,a0        ; a0 = ptr to command block
  183.     move.w    $e(sp),d0        ; get unit number
  184.     lsl.b    #5,d0            ; shift it into place
  185.     ori.b    #READ,d0        ; dev# + READ command
  186.     move.b    d0,(a0)+        ; 1st command byte = dev# + READ
  187.     move.b    $5(sp),(a0)+        ; MSB sector#
  188.     move.b    $6(sp),(a0)+        ; MidSB sector#
  189.     move.b    $7(sp),(a0)+        ; LSB sector#
  190.     move.b    $9(sp),(a0)+        ; transfer length (in sectors)
  191.     moveq    #0,d2            ; clear d2.l
  192.     move.w    $8(sp),d2        ; # sectors to read
  193.     sf    ncmd
  194.     move.l    $a(sp),-(sp)        ; buffer to transfer data to
  195.     bsr    _docmd            ; just do it
  196.     addq    #4,sp            ; cleanup stack
  197.     rts
  198.  
  199.  
  200. *-
  201. * _hwrite(sectno, count, buf, dev)
  202. * LONG sectno;         4(sp)
  203. * WORD count;         8(sp)
  204. * LONG buf;        $a(sp)    $b=high, $c=mid, $d=low
  205. * WORD dev;        $e(sp)
  206. *
  207. *-
  208. WRITE    equ    $a
  209.     .globl    _hwrite
  210. _hwrite:
  211.     bsr    clrcmdblk        ; clear the command block
  212.     lea    cmdblk,a0        ; a0 = ptr to command block
  213.     move.w    $e(sp),d0        ; get unit number
  214.     lsl.b    #5,d0            ; shift it into place
  215.     ori.b    #WRITE,d0        ; dev# + WRITE command
  216.     move.b    d0,(a0)+        ; 1st command block = dev# + WRITE
  217.     move.b    $5(sp),(a0)+        ; MSB sector#
  218.     move.b    $6(sp),(a0)+        ; MidSB sector#
  219.     move.b    $7(sp),(a0)+        ; LSB sector#
  220.     move.b    $9(sp),(a0)+        ; transfer length (in sectors)
  221.     move.w    #31,d1            ; bit # to be set
  222.     moveq    #0,d2            ; clear d2.l
  223.     bset.l    d1,d2            ; set direction bit: ST -> DMA
  224.     move.w    $8(sp),d2        ; # sectors to write
  225.     sf    ncmd
  226.     move.l    $a(sp),-(sp)        ; buffer to transfer data to
  227.     bsr    _docmd            ; just do it
  228.     addq    #4,sp            ; cleanup stack
  229.     rts
  230.  
  231.  
  232.  
  233. *+
  234. *  _inquiry - get device-specific parameters
  235. *
  236. *    Synopsis:    LONG _inquiry(physunit#, parms)
  237. *        WORD physunit#;            4(sp).W
  238. *        char *parms;            6(sp).L
  239. *
  240. *-
  241. INQUIRE    equ    $12
  242.     .globl    _inquiry
  243. _inquiry:
  244.     bsr    clrcmdblk        ; clear the command block
  245.     lea    cmdblk,a0        ; a0 = ptr to command block
  246.     move.w    4(sp),d0        ; d0 = physical unit #
  247.     lsl.b    #5,d0            ; shift it into place
  248.     ori.b    #INQUIRE,d0        ; physunit# + Inquiry command
  249.     move.b    d0,(a0)            ; byte 0 = dev# + opcode
  250.     move.b    #$10,4(a0)        ; byte 4 = allocation length
  251.     moveq    #1,d2            ; 1 sector of dma
  252.     move.l    6(sp),-(sp)        ; -> parameter block address
  253.     bsr    _docmd            ; just do it
  254.     addq    #4,sp            ; cleanup stack
  255.     rts
  256.  
  257.  
  258.  
  259. *+
  260. *  _rq_sense - get sense data from target
  261. *
  262. *    Synopsis:    LONG _rq_sense(physunit#, data)
  263. *        WORD physunit#;            4(sp).W
  264. *        char data[];            6(sp).L
  265. *
  266. *-
  267. RQSENSE    equ    $3
  268.     .globl    _rq_sense
  269. _rq_sense:
  270.     bsr    clrcmdblk        ; clear the command block
  271.     lea    cmdblk,a0        ; a0 = ptr to command block
  272.     move.w    4(sp),d0        ; d0 = (physunit# << 5) << 16
  273.     lsl.b    #5,d0            ; shift it into place
  274.     ori.b    #RQSENSE,d0        ; physunit# + Request Sense command
  275.     move.b    d0,(a0)            ; byte 0 = dev# + opcode
  276.     moveq    #1,d2            ; 1 sector of dma
  277.     move.w    d3,-(sp)        ; save d3
  278.     st    ncmd            ; don't clear flock when return
  279.     move.l    8(sp),-(sp)        ; -> parameter block address
  280.     bsr    _docmd            ; just do it
  281.     addq    #4,sp            ; cleanup stack
  282.     bne    rqsr            ; if unsuccessful, return
  283.     move.w    #1,d3            ; do the command 2 more times
  284. loop2x:    bsr    _shdc1
  285.     bne    rqsr
  286.     dbra    d3,loop2x
  287.     sf    ncmd            ; clear flock when return
  288.     bsr    _shdc1
  289. rqsr:    move.w    (sp)+,d3        ; restore d3
  290.     sf    ncmd            ; reset flag
  291.     rts
  292.  
  293.  
  294.  
  295. *+
  296. *  testunit - Test Unit Ready
  297. *
  298. *    Synopsis:    LONG testunit(dev)
  299. *        WORD dev;        4(sp).W
  300. *
  301. *-
  302. TSTUNIT    equ    $3
  303.     .globl    testunit
  304. testunit:
  305.     bsr    clrcmdblk        ; clear the command block
  306.     lea    cmdblk,a0        ; a0 = ptr to command block
  307.     move.w    4(sp),d0        ; d0 = (physunit# << 5) << 16
  308.     lsl.b    #5,d0            ; shift it into place
  309.     ori.b    #TSTUNIT,d0        ; physunit# + Test Unit command
  310.     move.b    d0,(a0)            ; byte 0 = dev# + opcode
  311.     sf    ncmd
  312.     bsr    _shdc            ; just do it
  313.     rts
  314.  
  315.  
  316.  
  317.  
  318.  
  319.